//
//  AppDelegate.m
//  HolyShit
//
//  Created by Robin on 2016/10/30.
//  Copyright © 2016年 HolyShit. All rights reserved.
//

#import "AppDelegate.h"
#import "HSLaunchVC.h"
#import "HSLoginVC.h"
#import "HSCollectionVC.h"

#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif

@interface AppDelegate ()<UNUserNotificationCenterDelegate>

@end

@implementation AppDelegate

#pragma mark - auto rotate
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    if (self.allowRotate) {
        return UIInterfaceOrientationMaskAll;
    }else{
        return UIInterfaceOrientationMaskPortrait;
    }
}

// 支持设备自动旋转
- (BOOL)shouldAutorotate
{
    if (self.allowRotate) {
        return YES;
    }
    return NO;
}

#pragma mark - appdelegate life circle

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    //注册推送
    [self registerUserNotification];
    //初始化3DTouch选项
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0) {
        [self init3DTouch];
    }
#endif
    //启动配置
    [self setupLaunch];
    // Override point for customization after application launch.
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    application.applicationIconBadgeNumber = 0;
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}


- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
    // 更新显示的徽章个数
    NSInteger badge = [UIApplication sharedApplication].applicationIconBadgeNumber;
    badge--;
    badge = badge >= 0 ? badge : 0;
    [UIApplication sharedApplication].applicationIconBadgeNumber = badge;
}

#pragma mark -


#pragma mark - method

- (void)setupLaunch
{
    
    [[UINavigationBar appearance] setBackgroundImage:[UIImage imageWithColor:HEXCOLOR(appNavColor)] forBarMetrics:UIBarMetricsDefault];
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
    
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    HSLaunchVC *tagVC = [HSLaunchVC new];
    UINavigationController *tagNav = [[UINavigationController alloc]initWithRootViewController:tagVC];
    self.window.rootViewController = tagNav;
    [self.window makeKeyAndVisible];
}

/** 注册用户通知 */
- (void)registerUserNotification
{
    /*
     注册通知(推送)
     申请App需要接受来自服务商提供推送消息
     */
    if (IOS10_OR_LATER) {
        //iOS 10 later
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        //必须写代理，不然无法监听通知的接收与点击事件
        center.delegate = self;
        [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (!error && granted) {
                //用户点击允许
                NSLog(@"推送授权成功");
            }else{
                //用户点击不允许
                NSLog(@"推送授权失败");
            }
        }];
        // 可以通过 getNotificationSettingsWithCompletionHandler 获取权限设置
        //之前注册推送服务，用户点击了同意还是不同意，以及用户之后又做了怎样的更改我们都无从得知，现在 apple 开放了这个 API，我们可以直接获取到用户的设定信息了。注意UNNotificationSettings是只读对象哦，不能直接修改！
        [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
            NSLog(@"========%@",settings);
        }];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
    else {
        // 判读系统版本是否是“iOS 8.0”以上
        // 定义用户通知类型(Remote.远程 - Badge.标记 Alert.提示 Sound.声音)
        UIUserNotificationType types = UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound;
        
        // 定义用户通知设置
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
        
        // 注册用户通知 - 根据用户通知设置
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    }
}

#pragma mark - 用户通知(推送)回调 _IOS 8.0以上使用

/** 已登记用户通知 */
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    // 注册远程通知（推送）
    [application registerForRemoteNotifications];
}

/** 远程通知注册成功委托 */
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSLog(@"\n>>>[DeviceToken Success]:%@\n\n", token);
}

/** 远程通知注册失败委托 */
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"\n>>>[DeviceToken Error]:%@\n\n", error.description);
}

#pragma mark - APP运行中接收到通知(推送)处理

/** APP已经接收到“远程”通知(推送) - (App运行在后台/App运行在前台) */
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    //    application.applicationIconBadgeNumber = 0; // 标签
    //    NSLog(@"\n>>>[Receive RemoteNotification]:%@\n\n", userInfo);
    //    /*
    //     消息类型,类别,关联ID,内容 	 对应字段 msg_type,type,source_id,text
    //     */
    //    [self handleWithPush:[userInfo objectForKey:@"payload"] application:(UIApplication *)application];
}

//ios<10
/** APP已经接收到“远程”通知(推送) - 透传推送消息  */
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
    // 处理APN
    NSLog(@"\n>>>[Receive RemoteNotification - Background Fetch]:%@\n\n", userInfo);
    
    application.applicationIconBadgeNumber = 0; // 标签
    
//    [self handlePushWithUserinfo:userInfo];
    
    completionHandler(UIBackgroundFetchResultNewData);
}

//下面这个代理方法，只会是app处于前台状态 前台状态 and 前台状态下才会走，后台模式下是不会走这里的
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
{
    // 这里真实需要处理交互的地方
    // 获取通知所带的数据
    NSString *notMess = [notification.request.content.userInfo objectForKey:@"aps"];
}

//ios>=10
//下面这个代理方法，只会是用户点击消息才会触发，如果使用户长按（3DTouch）、弹出Action页面等并不会触发。点击Action的时候会触发！
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
{
    NSDictionary *userInfo = response.notification.request.content.userInfo;
    // 处理APN
    NSLog(@"\n>>>[Receive RemoteNotification - Background Fetch]:%@\n\n", userInfo);
    [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
    
//    [self handlePushWithUserinfo:userInfo];
    
    completionHandler(UIBackgroundFetchResultNewData);
}

#pragma mark - 3D Touch

NSString *const _3DTouchZhuanLanKey = @"_3DTouchZhuanLanKey";
NSString *const _3DTouchLoginKey = @"_3DTouchLoginKey";
NSString *const _3DTouchCollectionKey = @"_3DTouchCollectionKey";

- (void)init3DTouch{
    /** type 该item 唯一标识符
     localizedTitle ：标题
     localizedSubtitle：副标题
     icon：icon图标 可以使用系统类型 也可以使用自定义的图片
     userInfo：用户信息字典 自定义参数，完成具体功能需求
     */
    /** 定义 shortcutItem  */
    UIApplicationShortcutIcon *icon1 = [UIApplicationShortcutIcon iconWithTemplateImageName:@"3d_shequ"];
    UIApplicationShortcutItem *createLiveItem = [[UIApplicationShortcutItem alloc]
                                                 initWithType:_3DTouchZhuanLanKey
                                                 localizedTitle:@"专栏"
                                                 localizedSubtitle:nil
                                                 icon:icon1 userInfo:nil];
    
    UIApplicationShortcutIcon *icon2 = [UIApplicationShortcutIcon iconWithTemplateImageName:@"3d_qd"];
    UIApplicationShortcutItem *watchLiveItem = [[UIApplicationShortcutItem alloc]
                                                initWithType:_3DTouchLoginKey
                                                localizedTitle:@"登录"
                                                localizedSubtitle:@""
                                                icon:icon2 userInfo:nil];
    
    UIApplicationShortcutIcon *icon3 = [UIApplicationShortcutIcon iconWithTemplateImageName:@"3d_mall"];
    UIApplicationShortcutItem *checkInItem= [[UIApplicationShortcutItem alloc]
                                             initWithType:_3DTouchCollectionKey
                                             localizedTitle:@"收藏"
                                             localizedSubtitle:@""
                                             icon:icon3 userInfo:nil];
    
    /** 将items 添加到app图标 */
    [UIApplication sharedApplication].shortcutItems = @[createLiveItem, watchLiveItem, checkInItem];
}

- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler
{
    UIViewController *vc = [UIViewController my_topViewController];
    if ([shortcutItem.type isEqualToString:_3DTouchZhuanLanKey]) {
        //专栏
        ((UITabBarController *)self.window.rootViewController).selectedIndex = 2;
    }
    else if([shortcutItem.type isEqualToString:_3DTouchLoginKey]){
        //登录
        if (![vc isKindOfClass:[HSLoginVC class]] && ![[NSUserDefaults standardUserDefaults] objectForKey:userNameKey]) {
            [vc my_push:[HSLoginVC new]];
        }
    }
    else if([shortcutItem.type isEqualToString:_3DTouchCollectionKey]){
        //收藏
        if(![[NSUserDefaults standardUserDefaults] objectForKey:userNameKey]){
            return [UIWindow showWarnMsg:@"请先登录"];
        }
        if (![vc isKindOfClass:[HSCollectionVC class]]) {
            [vc my_push:[HSCollectionVC new]];
        }
    }
}

#pragma mark - local notify

- (void)registerSignLocalNotification {
    UILocalNotification *notification = [self notificationWithKey:@"LocalSignKey"];
    if (notification) {
        return;
    }
    notification = [[UILocalNotification alloc] init];
    notification.fireDate = [self dateAtHour:19 minute:5];
    notification.timeZone = [NSTimeZone defaultTimeZone];
    notification.alertBody = @"😊你懂得~，养成每天打开的好习惯";
    notification.applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber + 1;
    notification.soundName = @"localSound.wav";
    
    NSDictionary *userDict = [NSDictionary dictionaryWithObject:@"sign local notification" forKey:@"LocalSignKey"];
    notification.userInfo = userDict;
    
    [self registerNotification:notification repeat:NSCalendarUnitDay];
}

- (NSDate *)dateAtHour:(NSUInteger)hour minute:(NSUInteger)minute
{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.dateFormat = @"yyyy-MM-dd HH:mm";
    NSDate *testDate = [formatter dateFromString:@"2017-01-01 19:00"];
    NSCalendar *calender = [NSCalendar autoupdatingCurrentCalendar];
    NSDateComponents *dateComponents = [calender components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:testDate];
    dateComponents.hour = hour;
    dateComponents.minute = minute;
    
    return [calender dateFromComponents:dateComponents];
}

// 取消某个本地推送通知
- (UILocalNotification *)notificationWithKey:(NSString *)key {
    // 获取所有本地通知数组
    NSArray *localNotifications = [UIApplication sharedApplication].scheduledLocalNotifications;
    
    for (UILocalNotification *notification in localNotifications) {
        NSDictionary *userInfo = notification.userInfo;
        if (userInfo) {
            // 根据设置通知参数时指定的key来获取通知参数
            NSString *info = userInfo[key];
            if (info != nil) {
                return notification;
            }
        }
    }
    return nil;
}

- (void)registerNotification:(UILocalNotification *)notification repeat:(NSCalendarUnit)repeat
{
    // ios8后，需要添加这个注册，才能得到授权
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
        UIUserNotificationType type =  UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound;
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:type
                                                                                 categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        notification.repeatInterval = repeat;
    } else {
        notification.repeatInterval = repeat;
    }
    [[UIApplication sharedApplication] scheduleLocalNotification:notification];
}

@end
